﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using Lib.Tools.Common;

namespace Lib.Tools.Data
{
    public static class DataSetHelper
    {
        /// <summary>
        /// 将DataRow 对象转换成字典对象
        /// </summary>
        /// <param name="row">数据行</param>
        /// <returns></returns>
        public static IDictionary<string, object> DataRowCvt2Dict(DataRow row)
        {
            return DataRowCvt2Dict(row, null);
        }
        /// <summary>
        /// 将DataRow 对象转换成字典对象
        /// </summary>
        /// <param name="row">数据行</param>
        /// <param name="filterColumns">要过滤掉的列名</param>
        /// <returns></returns>
        public static IDictionary<string, object> DataRowCvt2Dict(DataRow row, IList<string> filterColumns)
        {
            DataColumnCollection dcl = row.Table.Columns;
            IDictionary<string, object> dict = new Dictionary<string, object>();
            foreach (DataColumn dc in dcl)
            {
                string colName = dc.ColumnName;
                if (filterColumns == null || !filterColumns.Contains(colName))
                {
                    dict.Add(colName, row[colName]);
                }
            }
            return dict;
        }



        #region 将DataRow对象转换成元数据类型

        /// <summary>
        /// 获取行指定列的值
        /// </summary>
        /// <param name="dr"></param>
        /// <param name="cellName"></param>
        /// <returns></returns>
        public static object GetObj(DataRow dr, string cellName)
        {
            ArgsChecker.CheckArgumentNull("dr", dr, true);
            ArgsChecker.CheckArgumentNull("cellName", cellName, true);
            object obj = dr[cellName];
            return obj;
        }
        /// <summary>
        /// 是否是数据库NULL值
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsDBNull(object obj)
        {
            return (obj == null || obj == DBNull.Value);
        }

        /// <summary>
        /// 获取行指定列的值，如果为NULL 返回 Null
        /// </summary>
        /// <param name="dr"></param>
        /// <param name="cellName"></param>
        /// <returns></returns>
        public static string GetString(DataRow dr, string cellName)
        {
            return GetString(dr, cellName, null);
        }
        /// <summary>
        /// 获取行指定列的值，如果为DbNull或者为Null 则返回失败的值
        /// </summary>
        /// <param name="dr">行</param>
        /// <param name="cellName">列名</param>
        /// <param name="failVal">备选的值</param>
        /// <returns></returns>
        public static string GetString(DataRow dr, string cellName, string failVal)
        {
            object obj = GetObj(dr, cellName);
            return GetString(obj, failVal);
        }
        public static string GetString(object obj, string failVal)
        {
            if (IsDBNull(obj))
            {
                return failVal;
            }
            return obj.ToString();
        }

        public static DateTime? GetDateTime(DataRow dr, string cellName, DateTime? failVal)
        {
            object obj = GetObj(dr, cellName);
            if (IsDBNull(obj))
            {
                return failVal;
            }
            return Convert.ToDateTime(obj);
        }
        public static DateTime? GetDateTime(DataRow dr, string cellName)
        {
            return GetDateTime(dr, cellName, null);
        }

        public static int? GetInt(DataRow dr, string cellName, int? failVal)
        {
            object obj = GetObj(dr, cellName);
            return GetInt(obj, failVal);
        }
        public static int? GetInt(object obj, int? failVal)
        {
            if (IsDBNull(obj))
            {
                return failVal;

            }
            return Convert.ToInt32(obj);
        }
        public static int GetInt(DataRow dr, string cellName, int failVal)
        {
            object obj = GetObj(dr, cellName);
            return GetInt(obj, failVal);
        }
        public static int GetInt(object obj, int failVal)
        {
            if (IsDBNull(obj))
            {
                return failVal;

            }
            return Convert.ToInt32(obj);
        }

        public static bool GetBool(DataRow dr, string cellName, bool failVal)
        {
            object obj = GetObj(dr, cellName);
            return GetBool(obj, failVal);
        }
        public static bool GetBool(object obj, bool failVal)
        {
            if (IsDBNull(obj))
            {
                return failVal;

            }
            return Convert.ToBoolean(obj);
        }
        public static bool? GetBool(DataRow dr, string cellName, bool? failVal)
        {
            object obj = GetObj(dr, cellName);
            return GetBool(obj, failVal);
        }
        public static bool? GetBool(object obj, bool? failVal)
        {
            if (IsDBNull(obj))
            {
                return failVal;

            }
            return Convert.ToBoolean(obj);
        }

        #endregion

        #region 将DataTable转换成自定义类型
        /// <summary>
        /// 将DataTable转换成自定义类型的列表
        /// </summary>
        /// <typeparam name="TEntity"></typeparam>
        /// <param name="dataTable"></param>
        /// <param name="handle"></param>
        /// <returns></returns>
        public static List<TEntity> Cvt2EntityList<TEntity>(DataTable dataTable, MyFunc<DataRow, TEntity> handle)
        {
            if (handle == null)
            {
                throw new InvalidOperationException("handle is Null!");
            }
            List<TEntity> resultList = new List<TEntity>();
            foreach (DataRow entity in dataTable.Rows)
            {
                TEntity result = handle(entity);
                if (result != null)
                {
                    resultList.Add(result);
                }
            }
            return resultList;

        }

        /// <summary>
        /// 将DatatTable转换成字典
        /// </summary>
        /// <typeparam name="Key">任意类型（如果是自定义的类型，如果是引用类型 是按引用来比较的）</typeparam>
        /// <typeparam name="Value"></typeparam>
        /// <param name="table"></param>
        /// <param name="handle"></param>
        /// <returns></returns>
        public static Dictionary<Key, Value> GetDictionary<Key, Value>(DataTable table, MyFunc<DataRow, KeyValuePair<Key, Value>> handle)
        {
            if (handle == null)
            {
                throw new ArgumentNullException("handle");
            }
            Dictionary<Key, Value> dict = new Dictionary<Key, Value>(table.Rows.Count);
            foreach (DataRow drow in table.Rows)
            {
                KeyValuePair<Key, Value> keyVal = handle(drow);
                dict.Add(keyVal.Key, keyVal.Value);
            }

            return dict;
        }
        #endregion
    }
}
